// 这个文件中要定义一个函数,名为myAjax
// 这个函数的作用: 就是将ajax代码封装起来, 未来发送请求的时候, 可以简化我们的代码

// 我们封装函数的意义:
// 1. 学习如何封装工具函数
// 2. 为后面学习axios做铺垫

// 封装函数思考的问题:
// 1. 函数名叫什么  -> myAjax
// 2. 函数需要什么参数
//   请求方式
//   url
//   参数
// 3. 函数是否需要返回值,如果需要,返回值是什么
// 需要,需要返回的响应数据(xhr.responseText)

// 注意:封装工具函数时,可能传入的参数比较多.为了传递顺序不出错,一般都会选选择传入一个配置对象.配置对象中包含了函数中需要的参数
function myAjax(option) {
  return new Promise((resolve, reject) => {
    // 先判断option有没有传递数据,以及option是否是一个对象
    if (!option || typeof option !== 'object') return
    // 解构传入的配置对象
    let { url, method = 'get', params } = option
    // 判断如果没有传入url地址,则直接return
    if (!url) return
    // 创建xhr实例
    const xhr = new XMLHttpRequest()
    // http://localhost:5000/test?
    // params传入的是用户要上传给服务器的数据. 不管是get请求还是post请求,params都要求写成一个对象.然后由我们封装的这个myAjax函数拼接成url编码的字符串,上传给服务器
    // str 可能是拼接好的url字符串也可能是undefined
    let str = obj2urlencode(params)
    // 调用open方法
    // 如果当前method是get请求并且str是有内容的字符串,就需要将str拼接在url后面,如果是post请求就不需要
    if (method === 'get' && str) {
      url += `?${str}` // 将上传的参数拼接在url后面
      str = null // 参数已经拼接在url后面了,那么str的值后面就没用了呀,可以赋值为null.后面发请求的时候也可以直接将str传入send中
    }
    xhr.open(method, url)

    // 设置请求头
    if (method === 'post')
      xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
    // 如果是get请求,str一定是null, 如果是post请求,str可能是一个字符串可能是一个undefined
    xhr.send(str)

    // 接收响应
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        // 请求响应完成
        if (xhr.status === 200) {
          // 请求响应成功
          // 把响应主体的数据会添加给成功的promise的value属性
          resolve(xhr.responseText)
        } else {
          // 请求响应失败
          reject()
        }
      }
    }
  })
}

// 专门把传入参数对象转成url编码的字符串的函数
function obj2urlencode(params) {
  if (!params || typeof params !== 'object') return
  //   比如: params ==> {x: 1,y:2} ==> x=1&y=2
  // 下面拼接字符串的代码不推荐使用.原因: 1. 会产生大量的无用的字符串 2. 拼接也不方便,拼完还要再切掉&
  //   let str = ''
  //   for (key in params) {
  //     str += `${key}=${params[key]}&`
  //   }
  //   console.log(str)
  //   xhr.open(method, url)
  // 推荐使用下面的形式
  let arr = []
  for (key in params) {
    arr.push(`${key}=${params[key]}`)
  }
  return arr.join('&')
}
